package top.z.orm.handle.osql.core;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TransformResultSet {

    public static StringBuffer toJson(ResultSet rs) throws SQLException {
        StringBuffer      json                     = new StringBuffer();
        ResultSetMetaData resultData               = rs.getMetaData();
        int               columnCount              = resultData.getColumnCount();
        boolean           ignoreNull               = HoneyConfig.getHoneyConfig().isIgnoreNullInSelectJson();
        String            temp                     = "";
        boolean           dateWithMillisecond      = HoneyConfig.getHoneyConfig().isDateWithMillisecondInSelectJson();
        boolean           timeWithMillisecond      = HoneyConfig.getHoneyConfig().isTimeWithMillisecondInSelectJson();
        boolean           timestampWithMillisecond = HoneyConfig.getHoneyConfig().isTimestampWithMillisecondInSelectJson();

        while (rs.next()) {
            json.append(",{");
            for (int i = 1; i <= columnCount; i++) {
                if (rs.getString(i) == null && ignoreNull) {
                    continue;
                }
                json.append("\"");
                json.append(_toFieldName(resultData.getColumnName(i)));
                json.append("\":");
                if (rs.getString(i) != null) {
                    if ("String".equals(HoneyUtil.getFieldType(resultData.getColumnTypeName(i)))) {
                        json.append("\"");
                        temp = rs.getString(i);
                        temp = temp.replace("\\", "\\\\");
                        temp = temp.replace("\"", "\\\"");
                        json.append(temp);
                        json.append("\"");
                    } else if ("Date".equals(HoneyUtil.getFieldType(resultData.getColumnTypeName(i)))) {
                        if (dateWithMillisecond) {
                            json.append(rs.getDate(i).getTime());
                        } else {
                            try {
                                temp = rs.getString(i);
                                Long.valueOf(temp);
                                json.append(temp);
                            } catch (NumberFormatException e) {
                                json.append("\"");
                                json.append(temp.replace("\"", "\\\""));
                                json.append("\"");
                            }
                        }
                    } else if ("Time".equals(HoneyUtil.getFieldType(resultData.getColumnTypeName(i)))) {
                        if (timeWithMillisecond) {
                            json.append(rs.getTime(i).getTime());
                        } else {
                            try {
                                temp = rs.getString(i);
                                Long.valueOf(temp);
                                json.append(temp);
                            } catch (NumberFormatException e) {
                                json.append("\"");
                                json.append(temp.replace("\"", "\\\""));
                                json.append("\"");
                            }
                        }
                    } else if ("Timestamp".equals(HoneyUtil.getFieldType(resultData.getColumnTypeName(i)))) {
                        if (timestampWithMillisecond) {
                            json.append(rs.getTimestamp(i).getTime());
                        } else {
                            try {
                                temp = rs.getString(i);
                                Long.valueOf(temp);
                                json.append(temp);
                            } catch (NumberFormatException e) {
                                json.append("\"");
                                json.append(temp.replace("\"", "\\\""));
                                json.append("\"");
                            }
                        }
                    } else {
                        json.append(rs.getString(i));
                    }
                } else {
                    json.append(rs.getString(i));
                }
                if (i != columnCount) json.append(",");
            }
            if (json.toString().endsWith(",")) json.deleteCharAt(json.length() - 1);
            json.append("}");
        }
        if (json.length() > 0) {
            json.deleteCharAt(0);
        }
        json.insert(0, "[");
        json.append("]");
        return json;
    }

    private static String _toFieldName(String columnName) {
        return NameTranslateHandle.toFieldName(columnName);
    }

    public static List<String[]> toStringsList(ResultSet rs) throws SQLException {
        List<String[]>    list              = new ArrayList<>();
        ResultSetMetaData resultData        = rs.getMetaData();
        int               columnCount       = resultData.getColumnCount();
        boolean           nullToEmptyString = HoneyConfig.getHoneyConfig().isNullToEmptyStringInReturnStringList();
        String[]          str;
        while (rs.next()) {
            str = new String[columnCount];
            for (int i = 0; i < columnCount; i++) {
                if (nullToEmptyString && rs.getString(i + 1) == null) {
                    str[i] = "";
                } else {
                    str[i] = rs.getString(i + 1);
                }
            }
            list.add(str);
        }
        return list;
    }

    public static List<Map<String, Object>> toMapList(ResultSet rs) throws SQLException {
        List<Map<String, Object>> list        = new ArrayList<>();
        ResultSetMetaData         resultData  = rs.getMetaData();
        int                       columnCount = resultData.getColumnCount();
        Map<String, Object>       rowMap;
        while (rs.next()) {
            rowMap = new HashMap<>();
            for (int i = 1; i <= columnCount; i++) {
                rowMap.put(resultData.getColumnName(i), rs.getObject(i));
            }
            list.add(rowMap);
        }
        return list;
    }
}